﻿using System;
using Tao.OpenGl;

namespace Aeon.Framework.Objects
{

/// <summary>
/// Cube primitive class.
/// Uses up to 6 colors and textures, 1 for each face.
/// 
/// </summary>
public class Cube : ObjectBase
    {
    // --- Attributes:

    private Single dHeight;           // Height half dimension.
    private Single dWidth;            // Width half dimension.
    private Single dDepth;            // Depth half dimension.

    // --- Constructor:
    
    /// <summary>
    /// Cube constructor.
    /// 
    /// </summary>
    /// <param name="key"> Unique identifier. </param>
    /// <param name="origin"> Object origin.  </param>
    /// <param name="angle"> Object orientation. </param>
    /// <param name="length"> Cube side size. </param>
    public Cube(String key, Position origin, Orientation angle, Single length)
        : this(key,origin,angle,length,length,length,AeonMaterials.Default) { }

    /// <summary>
    /// Custom rectangular hexaedron constructor.
    /// 
    /// </summary>
    /// <param name="key"> Unique identifier. </param>
    /// <param name="origin"> Object origin.  </param>
    /// <param name="angle"> Object orientation. </param>
    /// <param name="height"> Rectangle height. </param>
    /// <param name="width"> Rectangle width. </param>
    /// <param name="depth"> Rectangle depth. </param>
    /// <param name="material"> Object material. </param>
    public Cube(String key, Position origin, Orientation angle, Single height, Single width, Single depth, AeonMaterial material)
        : base(key,origin,angle,material)
        {
        dDepth = depth/2;
        dWidth = width/2;
        dHeight = height/2;
        }

    // --- Public Methods:

    public override void Draw()
        {
        Gl.glTranslated(origin.xPos,origin.yPos,origin.zPos);
        Gl.glRotated(angle.xAng,1,0,0);
        Gl.glRotated(angle.yAng,0,1,0);
        Gl.glRotated(angle.zAng,0,0,1);

        Position BRF = new Position(dWidth,-dHeight,-dDepth);
        Position BLF = new Position(-dWidth,-dHeight,-dDepth);
        Position TLF = new Position(-dWidth,dHeight,-dDepth);
        Position TRF = new Position(dWidth,dHeight,-dDepth);

        // Front:
        Gl.glColor4f(material.Color.R, material.Color.G, material.Color.B, material.Color.A);
        material.Texture.Bind();
        
        Gl.glBegin(Gl.GL_QUADS);
        Gl.glNormal3i(0,0,-1);
        
        Gl.glTexCoord2f(1.0f, 0.0f);
        Gl.glVertex3f(BRF.xPos, BRF.yPos, BRF.zPos);        
        Gl.glTexCoord2f(0.0f, 0.0f);
        Gl.glVertex3f(BLF.xPos, BLF.yPos, BLF.zPos);        
        Gl.glTexCoord2f(0.0f, 1.0f);
        Gl.glVertex3f(TLF.xPos, TLF.yPos, TLF.zPos);        
        Gl.glTexCoord2f(1.0f, 1.0f);
        Gl.glVertex3f(TRF.xPos, TRF.yPos, TRF.zPos);
        
        Gl.glEnd();

        // Back:
        Gl.glColor4f(material.Color.R, material.Color.G, material.Color.B, material.Color.A);
        material.Texture.Bind();
        
        Gl.glBegin(Gl.GL_QUADS);
        Gl.glNormal3i(0,0,1);
        
        Gl.glTexCoord2f(1.0f, 0.0f);
        Gl.glVertex3f(TRF.xPos, TRF.yPos, -TRF.zPos);
        Gl.glTexCoord2f(0.0f, 0.0f);
        Gl.glVertex3f(TLF.xPos, TLF.yPos, -TLF.zPos);
        Gl.glTexCoord2f(0.0f, 1.0f);
        Gl.glVertex3f(BLF.xPos, BLF.yPos, -BLF.zPos);
        Gl.glTexCoord2f(1.0f, 1.0f);
        Gl.glVertex3f(BRF.xPos, BRF.yPos, -BRF.zPos);
        
        Gl.glEnd();

        // Left:
        Gl.glColor4f(material.Color.R, material.Color.G, material.Color.B, material.Color.A);
        material.Texture.Bind();
        
        Gl.glBegin(Gl.GL_QUADS);
        Gl.glNormal3i(-1,0,0);
        
        Gl.glTexCoord2f(1.0f, 0.0f);
        Gl.glVertex3f(BLF.xPos, BLF.yPos, BLF.zPos);
        Gl.glTexCoord2f(0.0f, 0.0f);
        Gl.glVertex3f(BLF.xPos, BLF.yPos, -BLF.zPos);
        Gl.glTexCoord2f(0.0f, 1.0f);
        Gl.glVertex3f(TLF.xPos, TLF.yPos, -TLF.zPos);
        Gl.glTexCoord2f(1.0f, 1.0f);
        Gl.glVertex3f(TLF.xPos, TLF.yPos, TLF.zPos);
        
        Gl.glEnd();

        // Right:
        Gl.glColor4f(material.Color.R, material.Color.G, material.Color.B, material.Color.A);
        material.Texture.Bind();
        
        Gl.glBegin(Gl.GL_QUADS);
        Gl.glNormal3i(1,0,0);
        
        Gl.glTexCoord2f(1.0f, 0.0f);
        Gl.glVertex3f(BRF.xPos, BRF.yPos, -BRF.zPos);
        Gl.glTexCoord2f(0.0f, 0.0f);
        Gl.glVertex3f(BRF.xPos, BRF.yPos, BRF.zPos);
        Gl.glTexCoord2f(0.0f, 1.0f);
        Gl.glVertex3f(TRF.xPos, TRF.yPos, TRF.zPos);
        Gl.glTexCoord2f(1.0f, 1.0f);
        Gl.glVertex3f(TRF.xPos, TRF.yPos, -TRF.zPos);
        
        Gl.glEnd();
        
        // Top:
        Gl.glColor4f(material.Color.R, material.Color.G, material.Color.B, material.Color.A);
        material.Texture.Bind();
        
        Gl.glBegin(Gl.GL_QUADS);
        Gl.glNormal3i(0,1,0);
        
        Gl.glTexCoord2f(1.0f, 0.0f);
        Gl.glVertex3f(TRF.xPos, TRF.yPos, TRF.zPos);
        Gl.glTexCoord2f(0.0f, 0.0f);
        Gl.glVertex3f(TLF.xPos, TLF.yPos, TLF.zPos);
        Gl.glTexCoord2f(0.0f, 1.0f);
        Gl.glVertex3f(TLF.xPos, TLF.yPos, -TLF.zPos);
        Gl.glTexCoord2f(1.0f, 1.0f);
        Gl.glVertex3f(TRF.xPos, TRF.yPos, -TRF.zPos);
        
        Gl.glEnd();

        // Bottom:
        Gl.glColor4f(material.Color.R, material.Color.G, material.Color.B, material.Color.A);
        material.Texture.Bind();
        
        Gl.glBegin(Gl.GL_QUADS);
        Gl.glNormal3i(0,-1,0);
        
        Gl.glTexCoord2f(1.0f, 0.0f);
        Gl.glVertex3f(BRF.xPos, BRF.yPos, BRF.zPos);
        Gl.glTexCoord2f(0.0f, 0.0f);
        Gl.glVertex3f(BRF.xPos, BRF.yPos, -BRF.zPos);
        Gl.glTexCoord2f(0.0f, 1.0f);
        Gl.glVertex3f(BLF.xPos, BLF.yPos, -BLF.zPos);
        Gl.glTexCoord2f(1.0f, 1.0f);
        Gl.glVertex3f(BLF.xPos, BLF.yPos, BLF.zPos);
        
        Gl.glEnd();
        }

    }


}